<template>
  <div>
    <el-row>
      <el-input
        v-if="data.canSearch"
        v-model="data.searchValue"
        style="margin-bottom: 8px"
        placeholder="Search"
      />
      <el-tree
        v-loading="treeLoading"
        ref="treeRef"
        node-key="id"
        :show-checkbox="data.canMultipleCheck"
        :data="data.treeData"
        :props="data.fieldNames"
        :highlight-current="true"
        :default-expand-all="data.autoExpandParent"
        :filter-node-method="filterNode"
        @node-expand="onExpand"
        @current-change="nodeSelect"
        style="width: 100%"
      >
        <template #default="{ node }" v-if="data.canEdite">
          <el-dropdown trigger="contextmenu" @command="(e) => onContextMenuClick(node, e)">
            <span>
              {{ node.label.substr(0, node.label.indexOf(data.searchValue)) }}
              <span style="color: #f50">{{ data.searchValue }}</span>
              {{
                node.label.substr(node.label.indexOf(data.searchValue) + data.searchValue.length)
              }}
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="1">添加子节点</el-dropdown-item>
                <el-dropdown-item command="2">修改节点</el-dropdown-item>
                <el-dropdown-item command="3">删除节点</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
      </el-tree>
    </el-row>
    <el-dialog
      :title="
        (data.opType == 1 ? '新增' : data.opType == 2 ? '更新' : '删除') +
        ':' +
        (data?.selectNode?.label || '')
      "
      v-model="data.showModal"
    >
      <el-form
        v-loading="modalInfo.confirmLoading"
        :model="data.selectNode"
        :layout="data.formInfo.layout"
        v-bind="data.formInfo.formItemLayout"
        label-width="150px"
      >
        <el-form-item
          label="节点标签(中文)"
          name="label"
          :required="data.opType == 1 || data.opType == 2"
        >
          <el-input v-model="data.selectNode.label" :disabled="data.opType == 3" />
        </el-form-item>
        <el-form-item
          label="节点名字(英文)"
          name="name"
          :required="data.opType == 1 || data.opType == 2"
        >
          <el-input v-model="data.selectNode.name" :disabled="data.opType == 3" />
        </el-form-item>
        <el-form-item label="节点全名" name="fullName">
          <el-input v-model="data.selectNode.fullName" :disabled="true" />
        </el-form-item>
        <el-form-item label="节点全ID" name="fullId">
          <el-input v-model="data.selectNode.fullId" :disabled="true" />
        </el-form-item>
        <el-form-item label="节点备注" name="remark">
          <el-input v-model="data.selectNode.remark" />
        </el-form-item>
        <el-form-item label="排序" name="orderNo">
          <el-input v-model="data.selectNode.orderNo" />
        </el-form-item>
        <el-form-item :wrapper-col="{ span: 14, offset: 8 }">
          <el-button
            type="primary"
            @click="
              () => {
                data.opType = 0
              }
            "
            >取消</el-button
          >
          <el-button style="margin-left: 10px" @click="modalInfo.submit">提交</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import request from '@/config/axios'
import {
  ElRow,
  ElTree,
  ElDropdown,
  ElDropdownMenu,
  ElDropdownItem,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElButton
} from 'element-plus'
import { deepClone } from '@/utils'
const props = defineProps({
  treeType: {
    type: String,
    required: false,
    default() {
      return ''
    }
  },
  canEdite: {
    type: Boolean,
    required: false,
    default() {
      return false
    }
  },
  canSearch: {
    type: Boolean,
    required: false,
    default() {
      return true
    }
  },
  canMultipleCheck: {
    type: Boolean,
    required: false,
    default() {
      return true
    }
  },
  checkedKeys: {
    type: Array,
    required: false,
    default() {
      return []
    }
  }
})
const treeRef = ref<InstanceType<typeof ElTree>>()
const treeLoading = ref(false)
const data = reactive({
  searchValue: '',
  treeData: [],
  fieldNames: { label: 'label', children: 'children' },
  expandedKeys: [],
  autoExpandParent: true,
  canMultipleCheck: props.canMultipleCheck,
  canEdite: props.canEdite,
  checkedKeys: props.checkedKeys,
  canSearch: props.canSearch,
  selectNode: {},
  opType: 0, //0 无操作,1 新增,2 更新,3 删除
  formInfo: {
    layout: 'horizontal',
    formItemLayout: {
      labelCol: { span: 6 },
      wrapperCol: { span: 16 }
    }
  },
  showModal: computed({
    get: () => !(data.opType == 0),
    set: (val) => {
      if (!val) {
        data.opType = 0
      }
    }
  })
})
const modalInfo = reactive({
  confirmLoading: false,
  submit: () => {
    modalInfo.confirmLoading = true
    let url = ''
    if (data.opType == 2) {
      url = '/infra/base/tree/editTreeNode'
    } else if (data.opType == 1) {
      url = '/infra/base/tree/addTreeNode'
    } else if (data.opType == 3) {
      url = '/infra/base/tree/delTreeNode'
    }
    request
      .post({
        url: url,
        data: data.selectNode
      })
      .then(() => {
        data.opType = 0
        loadTree()
      })
      .finally(() => {
        modalInfo.confirmLoading = false
      })
  }
})
const onContextMenuClick = (node, menuKey: number) => {
  data.selectNode = deepClone(node.data)
  if (menuKey == 1) {
    const parentId = data.selectNode.id
    const type = data.selectNode.type
    data.selectNode = { parentId: parentId, type: type }
  }
  data.opType = menuKey
}
function loadTree() {
  if (!props.treeType) {
    return
  }
  request
    .postFormFull({ url: '/infra/base/tree/getTree', data: { type: props.treeType } }, treeLoading)
    .then((value) => {
      data.treeData = value
    })
}
function nodeSelect(_d, node) {
  data.selectNode = node.data
}
function onExpand(keys: string[]) {
  data.expandedKeys = keys
  data.autoExpandParent = false
}
const filterNode = (value: string, data) => {
  if (!value) return true
  return data.label.includes(value)
}
watch(
  () => props.treeType,
  () => {
    loadTree()
  }
)
watch(
  () => props.checkedKeys,
  () => {
    data.checkedKeys = props.checkedKeys
  }
)
watch(
  () => data.searchValue,
  (newVal) => {
    treeRef.value!.filter(newVal)
  }
)
onMounted(() => {
  loadTree()
})
</script>
<style scoped>
#tree {
  background: white;
}
</style>
